package org.lqk.pool.zk;


import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PooledSocketConnectionFactory implements PooledObjectFactory<SocketConnection> {

	
	private SocketConnectionConfig socketConnectionConfig;
	private ServerAddressProvider serverAddressProvider;
	
	private static Logger log = LoggerFactory.getLogger(PooledSocketConnectionFactory.class);
	
	public PooledSocketConnectionFactory(SocketConnectionConfig socketConnectionConfig,ServerAddressProvider serverAddressProvider){
		this.socketConnectionConfig = socketConnectionConfig;
		this.serverAddressProvider = serverAddressProvider;
	}

	@Override
	public PooledObject<SocketConnection> makeObject() throws Exception {
		log.debug("makeObject");
		return new DefaultPooledObject<SocketConnection>(newSocketConnection());
	}
	
	private SocketConnection newSocketConnection() throws IOException{
		InetSocketAddress address = serverAddressProvider.selector();
		log.debug("host {},port {}",address.getHostName(),address.getPort());
		socketConnectionConfig.setHost(address.getHostName());
		socketConnectionConfig.setPort(address.getPort());
		// 在实际的操作中，socketConnectionConfig参数更加复杂
		GenericSocketConnection connection = new GenericSocketConnection(socketConnectionConfig);
		return connection;
	}

	@Override
	public void destroyObject(PooledObject<SocketConnection> p) throws Exception {
		SocketConnection connection = p.getObject();
		connection.destory();

	}

	@Override
	public boolean validateObject(PooledObject<SocketConnection> p) {
		SocketConnection connection = p.getObject();
		if(connection.isClosed()){
			return false;
		}
		return true;
	}

	@Override
	public void activateObject(PooledObject<SocketConnection> p) throws Exception {
		log.debug("activateObject");
		SocketConnection connection = p.getObject();
		if(null == connection || connection.isClosed()){
			connection = newSocketConnection();
		}
		// 清掉读写缓冲区
		connection.socket().getOutputStream().flush();
//		InputStream in = connection.socket().getInputStream();
//		byte[] b = new byte[1024];
//		int len = -1;
//		while((len = in.read(b)) > -1){}
	}

	@Override
	public void passivateObject(PooledObject<SocketConnection> p) throws Exception {
		SocketConnection connection = p.getObject();
		// 清掉读写缓冲区
		connection.socket().getOutputStream().flush();
//		InputStream in = connection.socket().getInputStream();
//		byte[] b = new byte[1024];
//		int len = -1;
//		while((len = in.read(b)) != -1){}
	}

}
